cmake_minimum_required(VERSION 3.0.0)
project(main VERSION 0.1.0)

include(CTest)
enable_testing()

find_package(PkgConfig REQUIRED)
pkg_check_modules(protobuf REQUIRED protobuf grpc++)
include(FindPythonInterp)

set(CMAKE_CXX_STANDARD 20)

add_library(ghrpc_async INTERFACE)
target_link_options(ghrpc_async INTERFACE "-L${protobuf_LIBRARY_DIRS}")
target_link_libraries(ghrpc_async INTERFACE pthread ${protobuf_LIBRARIES})
target_compile_options(ghrpc_async INTERFACE -fcoroutines)
add_library(proto_async_internel INTERFACE)
target_link_libraries(proto_async_internel INTERFACE ghrpc_async)
target_include_directories(proto_async_internel INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

execute_process(COMMAND which grpc_cpp_plugin OUTPUT_VARIABLE CPP_PLUGIN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
function(do_proto proto_file)
    get_filename_component(name_proto ${proto_file} NAME_WE)
    set(proto_folder ${name_proto})
    set(file_list ${proto_folder}/${name_proto}.pb.cc ${proto_folder}/${name_proto}.grpc.pb.cc ${proto_folder}/${name_proto}.pb.h ${proto_folder}/${name_proto}.grpc.pb.h ${proto_folder}/${name_proto}_client.hpp)
    add_custom_command(
        OUTPUT ${file_list}
        COMMAND mkdir -p ${proto_folder}
        COMMAND protoc "--grpc_out=${proto_folder}" "--cpp_out=${proto_folder}"  "--plugin=protoc-gen-grpc=${CPP_PLUGIN_PATH}" "--proto_path=${CMAKE_CURRENT_SOURCE_DIR}" "${proto_file}"
        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/generate_service.py ${CMAKE_CURRENT_SOURCE_DIR}/${proto_file} ${proto_folder}/${name_proto}_client.hpp
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${proto_file}
    )
    add_library(${name_proto}_lib STATIC)
    target_sources(${name_proto}_lib PRIVATE ${file_list})
    target_include_directories(${name_proto}_lib PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/${proto_folder})
    target_link_libraries(${name_proto}_lib PUBLIC proto_async_internel)
    
endfunction(do_proto)

option(BUILD_TEST_CODE OFF)
option(BUILD_UNIT_CODE OFF)
if(${BUILD_TEST_CODE})

    do_proto("test.proto")
    # add_library(proto_code protocpp/test.pb.cc protocpp/test.grpc.pb.cc)
    # target_link_libraries(proto_code PUBLIC proto_async_internel)

    add_executable(main main.cpp)
    target_link_libraries(main PUBLIC test_lib)
    add_executable(client client.cpp)
    target_link_libraries(client PUBLIC test_lib)
endif()
if(${BUILD_UNIT_CODE})
    add_subdirectory(unit_test)
endif()

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)


install(FILES proto_client.hpp proto_server_context.hpp proto_service.hpp function_traits.hpp TYPE INCLUDE)
install(FILES generate_service.py TYPE BIN  PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)
install(TARGETS ghrpc_async EXPORT proto_async_TARGETS )
install(EXPORT proto_async_TARGETS
        FILE ghrpc_async_targets.cmake
        NAMESPACE ghrpc_async::
        DESTINATION lib/cmake/ghrpc_async
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/ghrpc_async/ghrpc_asyncConfigVersion.cmake"
  VERSION 1.0.0
  COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/ghrpc_async/ghrpc_asyncConfig.cmake"
  INSTALL_DESTINATION lib/cmake/ghrpc_async
)
install(FILES
          "${CMAKE_CURRENT_BINARY_DIR}/ghrpc_async/ghrpc_asyncConfigVersion.cmake"
          "${CMAKE_CURRENT_BINARY_DIR}/ghrpc_async/ghrpc_asyncConfig.cmake"
        DESTINATION lib/cmake/ghrpc_async
)